#include "FlowSimFrmListener.h"

#include <iostream>

using namespace std;
using namespace FlowSim;
using namespace Ogre;

FlowSimFrmListener::FlowSimFrmListener(RenderWindow* win, Camera* cam, SceneManager* sceneMgr,
				       MyFlowSimGpu* flowSim) :
  ExampleFrameListener(win,cam,true,true), _sceneMgr(sceneMgr),_mouseDown(false),_continue(true),
  _flowSim(flowSim)
{
  
  mMouse->setEventCallback(this);
  mKeyboard->setEventCallback(this);
  mCamera->setPosition(200/2,200/2,128);
  
}

bool FlowSimFrmListener::frameStarted(const FrameEvent &evt)
{
  
  using namespace OIS;
  mRotX = 0;
  mRotY = 0;
  mTranslateVector = Ogre::Vector3::ZERO;
  if(mMouse)
    mMouse->capture();
  if(mKeyboard)
    mKeyboard->capture();
  
  moveCamera();
  _flowSim->update();
  return _continue;
}

bool FlowSimFrmListener::mouseMoved(const OIS::MouseEvent &e)
{
  using namespace OIS;
  if(e.state.buttonDown(MB_Right))
    {
      mTranslateVector.x += e.state.X.rel * 0.13;
      mTranslateVector.y -= e.state.Y.rel * 0.13;
    }
  else if(e.state.buttonDown(MB_Middle))
    {
      mTranslateVector.z -= e.state.Y.rel * 0.13;
    }
  else
    {
      //mRotX = Degree(-e.state.X.rel * 0.13);
      //mRotY = Degree(-e.state.Y.rel * 0.13);
    }
  return true;
}

bool FlowSimFrmListener::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
  return true;
}

bool FlowSimFrmListener::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
  
  switch(id)
    {
    case OIS::MB_Left:
      //_flowSim->testInterpolation(e.state.X.abs,e.state.Y.abs,mWindow->getWidth(),
      //		  mWindow->getHeight());
      //_flowSim->addSource(e.state.X.abs,(mWindow->getHeight()-1)-e.state.Y.abs,mWindow->getWidth(),
      //		  mWindow->getHeight());
      //_flowSim->addForce(e.state.X.abs,e.state.Y.abs,mWindow->getWidth(),
      //		 mWindow->getHeight());
      break;
    }
  return true;
}

bool FlowSimFrmListener::keyPressed(const OIS::KeyEvent &e)
{
  switch(e.key)
    {
    case OIS::KC_ESCAPE:
      _continue = false;
      break;
    case OIS::KC_A: //advance the flow simulation by a single time step
      //_flowSim->update();
      //_flowSim->reset();
      //_flowSim->trust(5.0);
       _flowSim->yaw(-10.0);
      break;
    case OIS::KC_D:
      _flowSim->yaw(10.0);
      break;
     case OIS::KC_W:
       _flowSim->trust(0.1);
       break;
     case OIS::KC_S:
       _flowSim->trust(-0.1);
	break;
    case OIS::KC_SPACE:
      _flowSim->fireMissile();
      break;
	case OIS::KC_E:
		_flowSim->reset();
	case OIS::KC_R:
		_flowSim->addDRate(0.01);
		break;
	case OIS::KC_T:
		_flowSim->addDRate(-0.01);
		break;
//     case OIS::KC_D:
//       _flowSim->changeDifRate(0.01);
//       break;
//     case OIS::KC_F:
//       _flowSim->changeDifRate(-0.01);
//       break;
     case OIS::KC_LEFT:
      
       break;
     case OIS::KC_RIGHT:
       
       break;
//     case OIS::KC_UP:
//       _flowSim->moveUp();
//       break;
//     case OIS::KC_DOWN:
//       _flowSim->moveDown();
//       break;
    }
  return true;
}

bool FlowSimFrmListener::keyReleased(const OIS::KeyEvent &e)
{
	return true;
}

bool FlowSimFrmListener::frameEnded(const FrameEvent& evt)
{
  return true;
}

void  FlowSimFrmListener::moveCamera()
{
  mCamera->yaw(mRotX);
  mCamera->pitch(mRotY);
  mCamera->moveRelative(mTranslateVector);
}
